using System;
using System.Collections.Generic;
using System.IO;
using log4net.Core;
using Quiki.ExpressionParsers;

namespace Quiki.DocumentGraphProcessors
{
    public class CopyImagesProcessor : IDocumentGraphProcessor
    {
        public CopyImagesProcessor(
            DocumentProcessorSettings settings,
            FileSet documentFiles,
            ILogger logger)
        {
            this.settings = settings;
            this.documentFiles = documentFiles;
            this.logger = logger;
        }

        public void Execute(DocumentGraph documentGraph)
        {
            foreach (WikiDocument document in documentGraph.Documents.Values)
                ProcessDocument(document, documentGraph);
        }

        private void ProcessDocument(WikiDocument document, DocumentGraph documentGraph)
        {
            logger.PushContext(document.FileName);
            ProcessElement(document.RootElement, document, documentGraph);
            logger.PopContext();
        }

        private void ProcessElement(WikiTextElement element, WikiDocument document, DocumentGraph documentGraph)
        {
            if (element.ElementType == WikiTextElementType.Image)
                CheckImage(element);

            foreach (WikiTextElement childElement in element.ChildElements)
                ProcessElement(childElement, document, documentGraph);
        }

        private void CheckImage(WikiTextElement element)
        {
            WikiImageElement imageElement = (WikiImageElement)element;

            string imageSourcePath = Path.Combine(Path.Combine(settings.InputDir, "images"), imageElement.Name);

            if (false == File.Exists(imageSourcePath))
                logger.Log(Level.Warn, "Image file {0} does not exist", imageSourcePath);
            else
            {
                string imageOutputFile = Path.Combine("images", imageElement.Name);

                if (false == documentFiles.HasFile (imageOutputFile))
                {
                    string imageDestPath = Path.Combine(settings.OutputDir, imageOutputFile);
                    Directory.CreateDirectory(Path.GetDirectoryName(imageDestPath));
                    File.Copy(imageSourcePath, imageDestPath, true);
                    documentFiles.RegisterFile(imageOutputFile);
                    logger.Log(Level.Info, "Copied image '{0}'", imageDestPath);
                }
            }
        }

        private readonly DocumentProcessorSettings settings;
        private readonly FileSet documentFiles;
        private readonly ILogger logger;
    }
}